import { Injector, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { catchError, finalize } from 'rxjs/operators';
import { AppComponentBase } from './app-component-base';

export class PagedResultDto {
    items: any[];
    totalCount: number;
}

export class EntityDto {
    id: number;
}

export class PagedRequestDto {
    skipCount: number;
    maxResultCount: number;
}

export class PageingInfo {
    pageSize = 10;
    pageNumber = 1;
    totalPages = 1;
    totalItems: number;
    isTableLoading = false;
}

export abstract class PagedListingComponentBase<EntityDto> extends AppComponentBase implements OnInit {

    public pageingInfo = new PageingInfo();
    public dataItems: EntityDto[] = [];

    private debounceTimeTag: any = undefined;

    ngOnInit(): void {
        this.refresh();
    }

    refresh(): void {
        // 多次重复调用refresh去重
        if ( this.debounceTimeTag) {
            clearTimeout(this.debounceTimeTag);
            this.debounceTimeTag = undefined;
        }
        this.debounceTimeTag = setTimeout(() => {
            this.debounceTimeTag = undefined;
            this.getDataPage(this.pageingInfo.pageNumber);
        }, 100);
    }

    public showPaging(result: PagedResultDto, pageNumber: number): void {
        this.pageingInfo.totalPages =
        ((result.totalCount - (result.totalCount % this.pageingInfo.pageSize)) / this.pageingInfo.pageSize) + 1;

        this.pageingInfo.totalItems = result.totalCount;
        this.pageingInfo.pageNumber = pageNumber;
    }

    public getDataPage(page: number): void {
        const req = new PagedRequestDto();
        req.maxResultCount = this.pageingInfo.pageSize;
        req.skipCount = (page - 1) * this.pageingInfo.pageSize;

        this.pageingInfo.isTableLoading = true;
        this.list(req, page).pipe(
            finalize(() => {
                this.pageingInfo.isTableLoading = false;
            }),
            catchError((error) => {
                return error;
            })
        ).subscribe((result: PagedResultDto) => {
            this.dataItems = result.items;
            this.showPaging(result, page);
        });
    }

    protected abstract list(request: PagedRequestDto, pageNumber: number): Observable<PagedResultDto>;
    protected abstract delete(entity: EntityDto): void;
}
